using LitJson;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Framework.Timer;
using System.Security.Cryptography;
using Framework.MyAtrribute;


namespace Framework.ObjectPool
{
    public enum PanelType
    {
        None,//默认
        MainPanel,//各场景下的主面板
        HitPanel,//弹窗面板
        BackPanel,//背景面板
        DialogPanel,
    }
    
    public class PanelManager
    {

        private PanelManager()
        {
        }

        static PanelManager _instance;
        private static bool mIsInit = false; //初始化是否完成

        public static PanelManager Instance
        {
            get
            {
                if (_instance == null && !mIsInit)
                {
                    _instance = new PanelManager();
                    //创建面板关闭事件监听
                    mIsInit = true;
                }

                return _instance;
            }
        }




        [SerializeField] private int blockTimeFlowPageCount; //禁流页面数量

        //打开过的单个面板
        Dictionary<string, PanelBase> openedPanelDic = new Dictionary<string, PanelBase>();
        Dictionary<string, SingleViewBase> openedSingleDic = new Dictionary<string, SingleViewBase>();
        Dictionary<PanelType, Transform> panelParentDic = new Dictionary<PanelType, Transform>(); //缓存了一些飘窗父物体
        //EventHappenPanel eventHappenPanel = null;
        


        #region 打开

        public void PreLoaingPanel<T>()where T : PanelBase
        {
            string typeName = typeof(T).ToString();

            ObjectPoolManager.Instance.PreLoadingObject(typeName, "prefabs/panelview", typeName, (success) =>
            {
                if (success)
                {
                    Debug.Log("预加载"+typeName+"成功");
                    // 进行后续处理
                }
                else
                {
                    Debug.LogError("预加载"+typeName+"失败");
                    // 处理加载失败情况
                }
            });

        }

        /// <summary>
        /// 打开一个面板(该面板默认处于激活状态)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent">父对象</param>
        /// <param name="args">面板所需参数</param>
        /// <param name="isActive">面板是否激活</param>
        /// <returns></returns>
        public T OpenPanel<T>(Transform parent, bool isActive = true, params object[] args) where T : PanelBase
        {
            if (parent == null)
            {
                Debug.LogError("将要打开的面板没有设定父类");
                return null;
            }

            string typeName = typeof(T).ToString();
            //string path = GetPanelPath(typeName); // 获取panel路径
            //PoolType thisType = (PoolType)Enum.Parse(typeof(PoolType), typeName);//获取对象池对象

            //防重复
            if (openedPanelDic.ContainsKey(typeName))
            {
                if (openedPanelDic[typeName] != null)
                    openedPanelDic[typeName].Closed();
                else openedPanelDic.Remove(typeName);
            }

            //Debug.Log(typeName);
            //获取面板
            GameObject plobj;
            bool isPoolExist;
            if (isActive)
                plobj = ObjectPoolManager.Instance.GetObject(typeName, "prefabs/panelview", typeName, out isPoolExist);
            else
                plobj = ObjectPoolManager.Instance.GetObjectForHidden(typeName, "prefabs/panelview", typeName,
                    out isPoolExist);
            
            plobj.transform.SetParent(parent, false);
            T targetPanel = plobj.GetComponent<T>();
            targetPanel.name = typeName;
            //如果忘记添加该组件
            if (null == targetPanel)
                targetPanel = plobj.AddComponent<T>();
            if (!isPoolExist)
            {
                //第一次打开时调用
                targetPanel.UIInit();
            }

            targetPanel.DataInit(args);
            targetPanel.ObjectType = typeName;
            targetPanel.OnOpenIng();
            openedPanelDic.Add(typeName, targetPanel);
            return targetPanel;
        }

        /// <summary>
        /// 打开一个面板并设定初始位置（默认面板处于激活状态）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent">父对象</param>
        /// <param name="localPostion">初始位置</param>
        /// <param name="args">参数</param>
        /// <param name="isActive">面板是否激活</param>
        /// <returns></returns>
        public T OpenPanel<T>(Transform parent, Vector2 localPostion, bool isActive = true, params object[] args) where T : PanelBase
        {
            if (parent == null)
            {
                Debug.LogError("将要打开的面板没有设定父类");
                return null;
            }

            string typeName = typeof(T).ToString();
            //string path = GetPanelPath.GetPanelPath(typeName); //利用泛型获取panel路径
            //PoolType thisType = (PoolType)Enum.Parse(typeof(PoolType), typeName); //获取对象池对象
            //获取面板
            GameObject plobj;
            bool isPoolExist;
            if (isActive)
                plobj = ObjectPoolManager.Instance.GetObject(typeName, "prefabs/panelview", typeName, out isPoolExist);
            else
                plobj = ObjectPoolManager.Instance.GetObjectForHidden(typeName, "prefabs/panelview", typeName,
                    out isPoolExist);

            plobj.transform.SetParent(parent, false);
            T targetPanel = plobj.GetComponent<T>();
            if (openedPanelDic.ContainsKey(typeName))
            {
                if (openedPanelDic[typeName] != null)
                    openedPanelDic[typeName].Closed();
                else openedPanelDic.Remove(typeName);
            }

            //targetPanel.name = typeName;
            plobj.transform.localPosition = localPostion;
            //如果忘记添加该组件
            if (null == targetPanel)
                targetPanel = plobj.AddComponent<T>();
            targetPanel.ObjectType = typeName;
            plobj.name = typeName;
            if (!isPoolExist)
            {
                //第一次打开时调用
                targetPanel.UIInit();
            }

            targetPanel.DataInit(args);
            targetPanel.OnOpenIng();
            openedPanelDic.Add(typeName, targetPanel);
            return targetPanel;
        }


        /// <summary>
        /// 打开一个SingleView（默认面板处于激活状态）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parentTrans"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public T OpenSingleView<T>(Transform parent, bool isActive = true, params object[] args) where T : SingleViewBase
        {
            if (parent == null)
            {
                Debug.LogError("将要打开的SingleView没有设定父类");
                return null;
            }

            string singleName = typeof(T).ToString();
            //string singlePath = PathConstant.GetPanelPath(singleName);
            //PoolType singleType = (PoolType)Enum.Parse(typeof(PoolType), singleName);
            if (openedSingleDic.ContainsKey(singleName))
            {
                if (openedSingleDic[singleName] != null)
                    openedSingleDic[singleName].Closed();
                else openedSingleDic.Remove(singleName);
            }

            //获取面板
            GameObject singleObj;
            bool isPoolExist;
            if (isActive)
                singleObj = ObjectPoolManager.Instance.GetObject(singleName, "prefabs/singleview", singleName,
                    out isPoolExist);
            else
                singleObj = ObjectPoolManager.Instance.GetObjectForHidden(singleName, "prefabs/singleview", singleName,
                    out isPoolExist);
            singleObj.transform.SetParent(parent, false);
            singleObj.name = singleName;
            T targetSingle = singleObj.GetComponent<T>();
            if (targetSingle == null)
                targetSingle = singleObj.AddComponent<T>();
            targetSingle.ObjectType = singleName;
            if (!isPoolExist)
            {
                //第一次打开时调用
                targetSingle.UIInit();
            }

            targetSingle.DataInit(args);
            targetSingle.OnOpenIng();
            if (!targetSingle.cannotRepeat)
                openedSingleDic.Add(singleName, targetSingle);
            return targetSingle;
        }

        
        #endregion

        #region 方法

        /// <summary>
        /// 获取面板的父类
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Transform GetParentOfPanel(PanelType type = PanelType.MainPanel)
        {
            string path = "";
            switch (type)
            {
                case PanelType.None:
                    path = CustomConstant.MainCamera;
                    break;
                case PanelType.MainPanel:
                    path = CustomConstant.MainPanel;
                    break;
                case PanelType.HitPanel:
                    path = CustomConstant.HitPanel;
                    break;
                case PanelType.BackPanel:
                    path = CustomConstant.BackPanel;
                    break;

                default:
                    break;
            }
            if (path == null)
            {
                Debug.LogError("试图寻找未定义的父物体类型");
                return null;
            }

            if (!panelParentDic.ContainsKey(type))
            {
                Transform trans = GameObject.Find(path).transform;
                if (trans == null)
                {
                    Debug.LogError("当前场景找不到该父物体" + path);
                    return null;
                }
                panelParentDic.Add(type, trans);
            }

            if (panelParentDic[type] == null)
            {
                Transform trans = GameObject.Find(path).transform;
                if (trans == null)
                {
                    Debug.LogError("当前场景找不到该父物体" + path);
                    return null;
                }
                panelParentDic[type] = trans;

            }
            return panelParentDic[type];
        }

        #endregion
        
        
        #region 关闭



        /// <summary>
        ///  关闭父物体下所有panel
        /// </summary>
        /// <param name="parent">父类对象</param>
        public void CloseAllPanel(Transform parent)
        {
            //Debug.Log("进入");
            int count;
            if (parent.childCount > 0)
                count = parent.childCount;
            else
                return;

            //Debug.Log(string.Format("关闭{0}物体下的所有含PanelBase的物体，子物体数量为{1}", parent.name, parent.childCount));

            for (int i = count - 1; i >= 0; i--)
            {
                PanelBase panelBase = parent.GetChild(i).GetComponent<PanelBase>();
                if (panelBase != null)
                    panelBase.Closed();
            }
        }

        /// <summary>
        ///  关闭自身的所有singleView
        /// </summary>
        /// <param name="parent">父类对象</param>
        public void CloseAllSingleViewFromSelf(Transform parent)
        {
            int count;
            //Debug.Log(string.Format("关闭{0}物体下的所有含PanelBase的物体，子物体数量为{1}", parent.name, parent.childCount));
            if (parent.childCount > 0)
                count = parent.childCount;
            else
                return;

            for (int i = count - 1; i >= 0; i--)
            {
                SingleViewBase singleBase = parent.GetChild(i).GetComponent<SingleViewBase>();
                if (singleBase != null)
                    singleBase.Closed();
            }
        }


        /// <summary>
        /// 关闭单个singleView
        /// </summary>
        /// <param name="parentTrans"></param>
        public void ClearTheSingle<T>(Transform parentTrans) where T : SingleViewBase
        {
            if (parentTrans == null)
                return;
            int count = parentTrans.childCount;
            for (int i = count - 1; i >= 0; i--)
            {
                T t = parentTrans.GetChild(i).GetComponent<T>();
                if (t != null)
                    t.Closed();
            }
        }

        /// <summary>
        /// 关闭单个面板
        /// </summary>
        /// <param name="panelBase"></param>
        public void OnPanelClosed(object[] args)
        {
            PanelBase panelBase = args[0] as PanelBase;
            if (openedPanelDic.ContainsKey(panelBase.ObjectType))
            {
                openedPanelDic.Remove(panelBase.ObjectType);
            }
        }

        public void OnSingleClosed(object[] args)
        {
            SingleViewBase single = args[0] as SingleViewBase;
            if (openedSingleDic.ContainsKey(single.ObjectType))
                openedSingleDic.Remove(single.ObjectType);
        }


        public void CloseEventPanel()
        {
            //Instance.eventHappenPanel = null;
        }

        #endregion


        #region 时停
        
        /// <summary>
        /// 添加时间暂停页面
        /// </summary>
        public void AddblockTimeFlowPage()
        {
            _instance.blockTimeFlowPageCount++;

        }

        /// <summary>
        /// 减少时间暂停页面
        /// </summary>
        public void RemoveblockTimeFlowPage()
        {
            _instance.blockTimeFlowPageCount--;
        }

        /// <summary>
        /// 是否时停
        /// </summary>
        /// <returns></returns>
        public bool isTimeFLow()
        {
            return _instance.blockTimeFlowPageCount > 0 ? true : false;
        }
        #endregion
    }

}